module(..., package.seeall)
require'lfs'
function fs_escape_id_but_keep_slash(id, options)
	return id:gsub("%%", "%%25"):gsub(":", "%%3A")
end
function fs_escape_id(id)
	assert(id and id:len() > 0)
	return fs_escape_id_but_keep_slash(id):gsub("/", "%%2F")
end
function fs_unescape_id(id)
	assert(id and id:len() > 0)
	return id:gsub("%%2F", "/"):gsub("%%3A", ":"):gsub("%%25", "%%")
end
function write_file(path, data, node)
	assert(path)
	assert(data)
	local f, err = io.open(path, "wb")
	assert(f, err)
	f:write(data)
	f:close()
end
function read_file(path, node)
	assert(path)
	local f, err = io.open(path,'rb')
	assert(f, err)
	local data = f:read("*all")
	f:close()
	return data
end
function read_file_if_exists(path,def)
	assert(path)
	local f, err = io.open(path,'rb')
	if f then
		local data = f:read("*all")
		f:close()
		return data
	else
		return def
	end
end
function file_exist(path,node)
	assert(path)
	local f, err = io.open(path)
	if f then
		f:close()
		return true
	end
end

function makedirs(dir)
	if lfs.attributes(dir) then return end
	local base
	if string.sub(dir,1,1)=='/' then base='' end
	for sub in string.gmatch(dir,'[^/]+') do
		base=((base and (base .. '/')) or '')..sub
		if not lfs.attributes(base) then
			lfs.mkdir(base)
		end
	end
end
function parientdir(dir)
	local parent_id = string.match(dir, "^(.+)/(.-)$") or ''
	return parent_id .. '/'
end

function suredir(filename)
	makedirs(parientdir(filename))
end

function rmdir(fspath)
	function _rmdir (path,prem)
		local mode = lfs.attributes(path,'mode')
		if mode == "directory" then
			for file in lfs.dir(path) do
				if file ~= "." and file ~= ".." then
					_rmdir(path .. '/' .. file)
				end
			end
			lfs.rmdir(path)
		else
			assert(os.remove(path))
		end
	end
	_rmdir(fspath)
end
function cleardir(fspath)
	local mode = lfs.attributes(path,'mode')
	if mode == "directory" then
		for file in lfs.dir(path) do
			if file ~= "." and file ~= ".." then
				rmdir(path .. '/' .. file)
			end
		end
	else
	end
end
local function check_in_filter(name,filter)
	if not filter then return true end
	if type(filter)=='function' then return filter(name) end
	for _,f in ipairs(filter) do
		if name:match(f) then return true end
	end
end

function scandir(fspath,needdir,needfile,filter)
	local re={}
	for file in lfs.dir(fspath) do
		if check_in_filter(file,filter) then
			local f = fspath..'/'..file
			local attr = lfs.attributes (f)
			assert (type(attr) == "table")
			if attr.mode == "directory" then
				if needdir then table.insert(re,{file=file,dir=true}) end
			else
				if needfile then table.insert(re,{file=file}) end
			end
		end
	end
	return re
end
function safedir(dir)
	if type(dir)=='string' and not string.find(dir,'..',1,1) then return true end
end
